package org.smarthings.things.automation.cep;

import java.util.Iterator;
import java.util.List;

import org.osgi.service.component.ComponentContext;
import org.smarthings.things.management.metadata.provider.ThingEventMetadataProvider;

import com.espertech.esper.client.Configuration;
import com.espertech.esper.client.EPServiceProvider;
import com.espertech.esper.client.EPServiceProviderManager;
import com.espertech.esper.client.EPStatement;
import com.espertech.esper.client.StatementAwareUpdateListener;

public class CEPEngineFacade {

	private EPServiceProvider eventProcessingService;
	private ThingEventStreamSpout thingEventsStreamSpout;

	public void activate(ThingEventMetadataProvider metadata, ComponentContext context) {
		Configuration configuration = new Configuration();
		List<String> topics = metadata.getThingEventTopics();
		Iterator<String> iter = topics.iterator();
		while (iter.hasNext()) {
			String topic = iter.next();
			configuration.addEventType(topic, metadata.getThingEventDescription(topic));
		}
		this.eventProcessingService = EPServiceProviderManager.getDefaultProvider(configuration);
		this.eventProcessingService.initialize();

		this.thingEventsStreamSpout = new ThingEventStreamSpout(eventProcessingService, topics);
		this.thingEventsStreamSpout.register(context);

	}

	public void deactivate(ComponentContext context) {
		this.eventProcessingService.getEPAdministrator().destroyAllStatements();
		this.eventProcessingService.destroy();
		this.thingEventsStreamSpout.unregister(context);
	}

	public String registerEventProcessingStatement(String expression, String name,
			StatementAwareUpdateListener listener) {
		boolean pattern = expression.startsWith("every");
		EPStatement statement = pattern ? eventProcessingService.getEPAdministrator()
				.createPattern(expression, name) : eventProcessingService.getEPAdministrator()
				.createEPL(expression, name);
		statement.addListener(listener);
		return statement.getName();
	}

	public void unregisterEventProcessingStatement(String identifier) {
		EPStatement statement = eventProcessingService.getEPAdministrator()
				.getStatement(identifier);
		if (statement == null) {
			throw new IllegalArgumentException("No statement with name " + identifier);
		}
		statement.destroy();
	}

}
